#include "rtpState.h"
#include <map>
#include <mutex>
#include <list>
#include <vector>
#ifdef WIN32
#include <WinSock2.h>

#ifdef min
#undef min
#endif

#endif
#include "sequence_number_util_jx.h"


#ifndef ntohll
#define ntohll(x) ((uint64_t)ntohl((uint32_t)((x) << 32)) | \
                   (uint64_t)ntohl((uint32_t)((x) & 0xffffffff)))
#endif
enum { kRtpCsrcSize = 15 }; // RFC 3550 page 13



struct RTPHeaderExtension {
	RTPHeaderExtension()
		: hasTransmissionTimeOffset(false),
		transmissionTimeOffset(0),
		hasAbsoluteSendTime(false),
		absoluteSendTime(0),
		hasAudioLevel(false),
		audioLevel(0) {}

	bool hasTransmissionTimeOffset;
	int32_t transmissionTimeOffset;
	bool hasAbsoluteSendTime;
	uint32_t absoluteSendTime;

	// Audio Level includes both level in dBov and voiced/unvoiced bit. See:
	// https://datatracker.ietf.org/doc/draft-lennox-avt-rtp-audio-level-exthdr/
	bool hasAudioLevel;
	uint8_t audioLevel;
};

struct RTPHeader {
	RTPHeader()
		: markerBit(false),
		payloadType(0),
		sequenceNumber(0),
		timestamp(0),
		ssrc(0),
		numCSRCs(0),
		paddingLength(0),
		headerLength(0),
		payload_type_frequency(0),
		extensionOffset(0),
		extension() {
		memset(&arrOfCSRCs, 0, sizeof(arrOfCSRCs));
	}

	bool markerBit;
	uint8_t payloadType;
	uint16_t sequenceNumber;
	uint32_t timestamp;
	uint32_t ssrc;
	uint8_t numCSRCs;
	uint32_t arrOfCSRCs[kRtpCsrcSize];
	uint8_t paddingLength;
	uint16_t headerLength;
	int payload_type_frequency;
	RTPHeaderExtension extension;
	uint16_t extensionOffset;
};


enum {
	kRtcpExpectedVersion = 2,
	kRtcpMinHeaderLength = 4,
	kRtcpMinParseLength = 8,

	kRtpExpectedVersion = 2,
	kRtpMinParseLength = 12
};


static bool rtpParse(RTPHeader& header, const void* p, size_t sizeLen)
{
	header.extensionOffset = 0;
	const uint8_t* const _ptrRTPDataBegin = (const uint8_t* const)p;
	const uint8_t* const _ptrRTPDataEnd = _ptrRTPDataBegin + sizeLen;
	const ptrdiff_t length = _ptrRTPDataEnd - _ptrRTPDataBegin;
	if (length < kRtpMinParseLength) {
		return false;
	}

	// Version
	const uint8_t V = _ptrRTPDataBegin[0] >> 6;
	// Padding
	const bool          P = ((_ptrRTPDataBegin[0] & 0x20) == 0) ? false : true;
	// eXtension
	const bool          X = ((_ptrRTPDataBegin[0] & 0x10) == 0) ? false : true;
	const uint8_t CC = _ptrRTPDataBegin[0] & 0x0f;
	const bool          M = ((_ptrRTPDataBegin[1] & 0x80) == 0) ? false : true;

	const uint8_t PT = _ptrRTPDataBegin[1] & 0x7f;

	const uint16_t sequenceNumber = (_ptrRTPDataBegin[2] << 8) +
		_ptrRTPDataBegin[3];

	const uint8_t* ptr = &_ptrRTPDataBegin[4];

	uint32_t RTPTimestamp = *ptr++ << 24;
	RTPTimestamp += *ptr++ << 16;
	RTPTimestamp += *ptr++ << 8;
	RTPTimestamp += *ptr++;

	uint32_t SSRC = *ptr++ << 24;
	SSRC += *ptr++ << 16;
	SSRC += *ptr++ << 8;
	SSRC += *ptr++;

	if (V != kRtpExpectedVersion) {
		printf("V:%d is invalid.\n", V);
		return false;
	}

	const uint8_t CSRCocts = CC * 4;

	if ((ptr + CSRCocts) > _ptrRTPDataEnd) {
		printf("!!!! ptr:%p, CSRCocts:%d, _ptrRTPDataEnd:%p is invalid.\n", ptr, CSRCocts, _ptrRTPDataEnd);
		return false;
	}

	header.markerBit = M;
	header.payloadType = PT;
	header.sequenceNumber = sequenceNumber;
	header.timestamp = RTPTimestamp;
	header.ssrc = SSRC;
	header.numCSRCs = CC;
	header.paddingLength = P ? *(_ptrRTPDataEnd - 1) : 0;

	for (unsigned int i = 0; i < CC; ++i) {
		uint32_t CSRC = *ptr++ << 24;
		CSRC += *ptr++ << 16;
		CSRC += *ptr++ << 8;
		CSRC += *ptr++;
		header.arrOfCSRCs[i] = CSRC;
	}

	header.headerLength = 12 + CSRCocts;

	// If in effect, MAY be omitted for those packets for which the offset
	// is zero.
	header.extension.hasTransmissionTimeOffset = false;
	header.extension.transmissionTimeOffset = 0;

	// May not be present in packet.
	header.extension.hasAbsoluteSendTime = false;
	header.extension.absoluteSendTime = 0;

	// May not be present in packet.
	header.extension.hasAudioLevel = false;
	header.extension.audioLevel = 0;

	if (X) {
		/* RTP header extension, RFC 3550.
		0                   1                   2                   3
		0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
		+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
		|      defined by profile       |           length              |
		+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
		|                        header extension                       |
		|                             ....                              |
		*/
		const ptrdiff_t remain = _ptrRTPDataEnd - ptr;
		if (remain < 4) {
			printf("remain:%d is invalid.\n", remain);
			return false;
		}
		header.extensionOffset = header.headerLength;
		header.headerLength += 4;
		

		uint16_t definedByProfile = *ptr++ << 8;
		definedByProfile += *ptr++;

		uint16_t XLen = *ptr++ << 8;
		XLen += *ptr++; // in 32 bit words
		XLen *= 4; // in octs

		if (remain < (4 + XLen)) {
			printf("remain:%d XLen:%d is definedByProfile:%d, invalid.\n", remain, XLen, definedByProfile);
			return false;
		}
		header.headerLength += XLen;
	}
	return true;
}


/*
   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |       0xBE    |    0xDE       |           length=2            |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  | ID=1  | L=1   |   transport sequence number   | ID=2  |  L=7  |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                               tag                             |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                               tag                             |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
struct RtpExtOneByteHeader
{
	uint8_t     len : 4;      // rtp扩展的长度
	uint8_t     ID : 4;       // id值
};

struct RTPHeaderExtStruct
{
	uint16_t profile;
	/// the length of extentions(The unit is DWORD)
	uint16_t length;
	/// list of extentions
	uint32_t startofexts;
};
// 不需要填写数据时，可以将pContent设置为空指针
// 不需要检查长度时，或长度不确定，可以设置为0，当设置为0时，会返回长度
static int GetOneByteExtHeaderContent(const uint8_t* pExtContentStart, size_t uExtBytes, uint8_t uId, uint8_t* pContent, size_t& uContentLen)
{
	const uint8_t* pEnd = pExtContentStart + uExtBytes;
	const uint8_t* ptr = pExtContentStart;
	RtpExtOneByteHeader* pExtHeader = nullptr;
	int ret = -1;

	while (ptr < pEnd)
	{
		pExtHeader = (RtpExtOneByteHeader*)ptr;
		// 指针往下偏移
		ptr++;
		// pad
		if (pExtHeader->ID == 0)
		{
			continue;
		}
		if (pExtHeader->ID == 15)
		{
			// invalid value
			break;
		}
		// 错误的长度
		if (ptr + pExtHeader->len + 1 > pEnd)
		{
			break;
		}
		if (pExtHeader->ID == uId)
		{
			// 仅当长度非0时，检查
			if (uContentLen)
			{
				if (pExtHeader->len + 1 != (int)uContentLen)
				{
					// 长度校验有问题
					break;
				}
				// 拷贝数据
				if (pContent)
				{
					memcpy(pContent, ptr, uContentLen);
				}
			}
			else
			{
				uContentLen = pExtHeader->len + 1;
			}
			ret = 0;
			break;
		}
		ptr += (pExtHeader->len + 1);
	}

	return ret;
}

static int64_t getCurrentTicket()
{
	return  std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
}
typedef struct SeqInfo_
{
	uint64_t m_iTimeStamp=0;
	int64_t m_iSeq=0;
	int64_t m_iMaxSeq=0;
	int64_t m_iByteSize=0;

}SeqInfo;

typedef struct DateCache_
{
	int32_t m_iPayLoadType = 0;
	uint32_t m_uPeerSsrc = 0;
	uint32_t m_uPeerCsrc = 0;

	uint64_t m_uExtValueTrackId = 0;

	uint64_t m_uCumulativeLost = 0;       // 累计丢包数
	uint64_t m_uPacketCount = 0;       // 表示累计发包数，或者累计收包数
	uint64_t m_uOutOfOrderCount = 0; // 乱序包数

	uint64_t m_uOutOfOrderDiffMax = 0; // 最大乱序差


	int64_t m_iMaxSequenceNum = -1; // 当前最大seq 
	int64_t m_iMinSequenceNum = -1; // 最小的seq

	int64_t m_iAccumulateByteSize = 0;


	jx::SeqNumUnwrapper<uint16_t> m_oSeqNum;
	

	std::list<SeqInfo> m_oListSeq;
	std::list<SeqInfo> m_oListSeqMayMiss;

	int64_t m_iTimeStampPre = 0;

	int64_t m_iTimeStampPreUpdate = 0;
	float m_fFractionLostMax = 0;

}DataCache;
class rtpState
{
public:
	using Ptr = std::shared_ptr<rtpState>;
	rtpState(RtpStateParameter oRtpStateParameter)
	{
		m_oRtpStateParameter = oRtpStateParameter;
	}
	~rtpState() {};
	void  rtpParseExtension(int8_t* pData, int32_t iLen, RTPHeader& header, uint64_t& ullExtValue)
	{
		if (header.extensionOffset && m_oRtpStateParameter.iTrackExtensionIndex)
		{
			//跳过扩展字段, 直接复制RTP负载
			//int iExtLen = 4/*扩展头长度*/ + pXRTPPacket->GetExtLen()/*扩展数据长度*/; //此时pRTPPacket中并未包含扩展字段, 不能使用pRTPPacket
			// changed by gc 20200420 必须考虑csrc的影响
			RTPHeaderExtStruct* pHdrExt = (RTPHeaderExtStruct*)((char*)pData + header.extensionOffset);
			int32_t iExtLen = 4/*扩展头长度*/ + (4 * ntohs(pHdrExt->length))/*扩展数据长度*/;
			if (pHdrExt->profile == 0xDEBE)
			{
				uint64_t uExt = 0;
				size_t uCheckLen = sizeof(uExt);

				// warning! 暂时写死eMultiplexRtpX，后续应当根据协商的结果确定
				uint8_t uid = (uint8_t)m_oRtpStateParameter.iTrackExtensionIndex;
				if (GetOneByteExtHeaderContent((uint8_t*)(&pHdrExt->startofexts), iExtLen, uid, (uint8_t*)&uExt, uCheckLen))
				{
					// 如果解析不到trackid 也可能是单呼，bwe 模式，
					//return ;
				}
				//ullExtValue = htonll_s(uExt);
				ullExtValue = ntohll(uExt);

			}
		}
	}
	int32_t IncomingRtp(const int8_t* pData, int32_t iLen)
	{
		std::lock_guard<std::mutex> lk(m_mutex);
		if (m_bIsPause)
		{
			return 0;
		}
		
		RTPHeader header;
		int8_t* ptr = (int8_t*)pData;
		int32_t tLen = iLen;

		bool bHasRelayId = false;
		if (iLen >= 8)
		{
			const char relayidMagicNum[4] = { 0xaa, 0xab, 0xac, 0xad };
			bHasRelayId = !memcmp(relayidMagicNum, pData, sizeof(relayidMagicNum));
		}
		else
		{
			return -1;
		}
		if (bHasRelayId)
		{
			ptr = ptr + 8;
			tLen = iLen - 8;
		}
		bool ret =  rtpParse(header, ptr, tLen);
		if (!ret)
		{
			return -2;
		}
		
		CacheByteSize(iLen);

		std::vector<uint32_t > tSsrcVec;

		std::map<uint32_t, std::shared_ptr<DataCache>>::iterator it = m_mapDate.find(header.ssrc);
		if (it != m_mapDate.end())
		{
			std::shared_ptr<DataCache> ptr = it->second;

			CacheData(ptr, header, iLen, tSsrcVec);
		}
		else
		{
			uint64_t ullExtValue = 0;
			rtpParseExtension(ptr, tLen, header, ullExtValue);

			std::shared_ptr<DataCache> ptr = std::make_shared<DataCache>();
			m_mapDate[header.ssrc] = ptr;
			ptr->m_iPayLoadType = header.payloadType;
			ptr->m_uPeerSsrc = header.ssrc;
			ptr->m_uExtValueTrackId = ullExtValue;
			if (header.numCSRCs > 0)
			{
				ptr->m_uPeerCsrc = header.arrOfCSRCs[0];
			}
			CacheData(ptr, header, iLen, tSsrcVec);


		}
		if (tSsrcVec.size() > 0)
		{
			ResetStateSsrc(tSsrcVec);
		}
		return 0;
	}
	int32_t GetRtpStateNumOfSsrc()
	{
		std::lock_guard<std::mutex> lk(m_mutex);
		return m_mapDate.size();
	}
	int32_t GetRtpStateInfo(RtpState* oRtpStateArray, int32_t iMaxRtpStateNum)
	{
		// 拷贝副本来计算
		std::map<uint32_t, DataCache> t_mapDate;
		{
			std::lock_guard<std::mutex> lk(m_mutex);
			
			int64_t t_time = getCurrentTicket();
			std::map<uint32_t, std::shared_ptr<DataCache>>::iterator it = m_mapDate.begin();
			for (; it != m_mapDate.end(); it++)
			{
				std::shared_ptr<DataCache> oDataCache = it->second;

				{
					// 可能很久没有输入包

					int32_t iRet = EraseTimeOutPacket(oDataCache->m_oListSeq, t_time);
					oDataCache->m_uPacketCount += iRet;
					iRet = EraseTimeOutPacket(oDataCache->m_oListSeqMayMiss, t_time);
					oDataCache->m_uCumulativeLost += iRet;
				}

				t_mapDate[it->first] = *oDataCache;
			}

		}
		
		int32_t tIndex = 0;
		int64_t t_time = getCurrentTicket();
		std::map<uint32_t, DataCache>::iterator it = t_mapDate.begin();
		for (; it != t_mapDate.end() && tIndex < iMaxRtpStateNum; it++, tIndex++)
		{
			DataCache oDataCache = it->second;



			// 总丢包率计算
			uint64_t t_uCumulativeLost = oDataCache.m_uCumulativeLost + oDataCache.m_oListSeqMayMiss.size();
			// 总包数计算
			uint64_t t_uPacketCountAll = oDataCache.m_uPacketCount + oDataCache.m_oListSeq.size();
			// 应该收到包数
			uint64_t t_uPacketCount = oDataCache.m_iMaxSequenceNum - oDataCache.m_iMinSequenceNum + 1;
#if 0
			float t_uFractionLostAll = t_uCumulativeLost * 1.0f / t_uPacketCount;
#else
			float t_uFractionLostAll = t_uCumulativeLost * 1.0f / (t_uPacketCountAll + t_uCumulativeLost);
#endif
			// 此处计算实时丢包率
			// 计算m_oListSeq 前面1s 时间收到的最大seq 差值


			float f_uFractionLost = 0.0f;
			int32_t iPacketFrequency = 0;
			int32_t ibps = 0;
			if(oDataCache.m_oListSeq.size() >= 2)
			{
				std::list<SeqInfo>::iterator it = oDataCache.m_oListSeq.begin();
				std::list<SeqInfo>::iterator it_end = oDataCache.m_oListSeq.end();
				it_end--;

				uint64_t firstTime = it->m_iTimeStamp;
				uint64_t endTime = it_end->m_iTimeStamp;
				int64_t firstMaxSeq = it->m_iMaxSeq;
				int64_t endUseMaxSeq = it_end->m_iMaxSeq;

				int64_t firstByteSize = it->m_iByteSize;
				int64_t endByteSize = it_end->m_iByteSize;

				int64_t half_timeOut = (endTime - firstTime) / 2;

				for (; it != oDataCache.m_oListSeq.end(); it++)
				{
					if (it->m_iTimeStamp - firstTime >= half_timeOut)
					{
						endUseMaxSeq = it->m_iMaxSeq;
						break;
					}
				}

				// 计算前一半时间真正丢包的个数
				int32_t tLossCount = 0;
				std::list<SeqInfo>::iterator it1 = oDataCache.m_oListSeqMayMiss.begin();
				for (; it1 != oDataCache.m_oListSeqMayMiss.end(); it1++)
				{
					if (it1->m_iTimeStamp - firstTime <= half_timeOut)
					{
						tLossCount++;
					}
					else
					{
						break;
					}

				}
				if (endUseMaxSeq != 0)
				{
					// 计算期望收到的包
					int64_t t_exp = endUseMaxSeq - firstMaxSeq;
					f_uFractionLost = t_exp == 0? 0: tLossCount * 1.0f / t_exp;

				}
				{
					int32_t dif = endTime - firstTime;
					iPacketFrequency = dif > 0 ? oDataCache.m_oListSeq.size() * 1000 / dif : 0;

					int64_t difByteSize = endByteSize - firstByteSize;
					ibps = dif > 0 ? difByteSize * 1000 * 8/ dif : 0;
		
				}
				
			}
			else if (oDataCache.m_oListSeq.size() == 0)
			{
				// 丢包率为 100% 因为有一段时间没有收到包
				if (oDataCache.m_iTimeStampPre != 0)
				{
					// 实时丢包率为100%
					f_uFractionLost = 1.0f;
				}
				else
				{
					// 实时丢包率为0
					f_uFractionLost = 0.0f;
				}
			}
			// 暂停情况需要修正
			if (m_bIsPause)
			{
				f_uFractionLost = 0.0f;
				iPacketFrequency = 0;
				ibps = 0;
			}
			
			// 和时间有关系
			oRtpStateArray[tIndex].fFractionLost = f_uFractionLost;
			oRtpStateArray[tIndex].iPacketFrequency = iPacketFrequency;
			oRtpStateArray[tIndex].ibps = ibps;
			
			oRtpStateArray[tIndex].uPacketCount = t_uPacketCountAll;
			oRtpStateArray[tIndex].uCumulativeLost = t_uCumulativeLost;
			oRtpStateArray[tIndex].fFractionLostAll = t_uFractionLostAll;
			oRtpStateArray[tIndex].uPeerSsrc = oDataCache.m_uPeerSsrc;
			oRtpStateArray[tIndex].iPayLoadType = oDataCache.m_iPayLoadType;
			oRtpStateArray[tIndex].uOutOfOrderCount = oDataCache.m_uOutOfOrderCount;
			oRtpStateArray[tIndex].uOutOfOrderDiffMax = oDataCache.m_uOutOfOrderDiffMax;
			oRtpStateArray[tIndex].fFractionLostMax = oDataCache.m_fFractionLostMax;

			/*
			if(m_oListByte.size() >= 2)
			{
				// 计算带宽
				std::list<SeqInfo>::iterator it = m_oListByte.begin();
				std::list<SeqInfo>::iterator it_end = m_oListByte.end();
				it_end--;


				uint64_t firstTime = it->m_iTimeStamp;
				uint64_t endTime = it_end->m_iTimeStamp;
				int32_t difT = endTime - firstTime;
				int64_t difMaxByte = it_end->m_iMaxSeq - it->m_iMaxSeq;
				int32_t ibps = difT > 0 ? difMaxByte * 1000 * 8/ difT : 0;

			}
			*/
			
		}
		//oRtpStateInfo.iRtpStateNum = tIndex;
		return tIndex;
	}


	int32_t RtpStatePause()
	{
		std::lock_guard<std::mutex> lk(m_mutex);
		m_bIsPause = true;
		return 0;
	}

	//oHandle input 输入句柄
	// return 0 成功
	int32_t RtpStateResume()
	{
		std::lock_guard<std::mutex> lk(m_mutex);
		ResetStateAll();
		m_bIsPause = false;
		return 0;
	}


private:
	// 返回过期包个数
	int32_t EraseTimeOutPacket(std::list<SeqInfo> &oSeqInfoList, int64_t iCurrentTime)
	{
		int32_t iCount = 0;
		while (oSeqInfoList.size() > 0)
		{
			std::list<SeqInfo>::iterator it = oSeqInfoList.begin();
			if (iCurrentTime - it->m_iTimeStamp > m_oRtpStateParameter.iCacheDuration)
			{
				oSeqInfoList.erase(it);
				iCount++;
			}
			else
			{
				break;
			}

		}
		return iCount;
	}
	void CacheByteSize(int32_t iLen)
	{
		m_uByteSize += iLen;
		int64_t t_time = getCurrentTicket();

		SeqInfo tSeqInfo;
		tSeqInfo.m_iTimeStamp = t_time;
		tSeqInfo.m_iMaxSeq = m_uByteSize;

		m_oListByte.push_back(tSeqInfo);

		EraseTimeOutPacket(m_oListByte, t_time);
	}
	// 对所有ssrc 重置部分状态，累加数据不变，只是把最大的seq 设置当前，把缓存清理，被清理的数据需要计入累加数据中
	void ResetStateAll()
	{
		std::map<uint32_t, std::shared_ptr<DataCache>>::iterator it = m_mapDate.begin();
		for (; it != m_mapDate.end(); it++)
		{
			std::shared_ptr<DataCache> oDataCache = it->second;

			// 可能很久没有输入包
			oDataCache->m_uPacketCount += oDataCache->m_oListSeq.size();
			oDataCache->m_oListSeq.clear();

			oDataCache->m_uCumulativeLost += oDataCache->m_oListSeqMayMiss.size();
			oDataCache->m_oListSeqMayMiss.clear();

			oDataCache->m_iMaxSequenceNum = -1;
			
		}
	}

	// 对指定的的ssrc 和对应的csrc 做重置操作
	void ResetStateSsrc(std::vector<uint32_t> oCsrcVec)
	{
		for (int i = 0; i < oCsrcVec.size(); i++)
		{
			std::map<uint32_t, std::shared_ptr<DataCache>>::iterator it = m_mapDate.begin();
			for (; it != m_mapDate.end(); it++)
			{
				std::shared_ptr<DataCache> oDataCache = it->second;

				if (oDataCache->m_uPeerCsrc == 0)
				{
					
					if (oDataCache->m_uPeerSsrc == oCsrcVec[i])
					{
						oDataCache->m_uPacketCount += oDataCache->m_oListSeq.size();
						oDataCache->m_oListSeq.clear();

						oDataCache->m_uCumulativeLost += oDataCache->m_oListSeqMayMiss.size();
						oDataCache->m_oListSeqMayMiss.clear();

						oDataCache->m_iMaxSequenceNum = -1;

					}
				}
				else
				{
					if (oDataCache->m_uPeerCsrc == oCsrcVec[i])
					{
						oDataCache->m_uPacketCount += oDataCache->m_oListSeq.size();
						oDataCache->m_oListSeq.clear();

						oDataCache->m_uCumulativeLost += oDataCache->m_oListSeqMayMiss.size();
						oDataCache->m_oListSeqMayMiss.clear();

						oDataCache->m_iMaxSequenceNum = -1;

					}
				}

				
			}
		}
		
	}
	void CacheData(std::shared_ptr<DataCache> oDataCache, RTPHeader &oRTPHeader, int32_t iByteSize, std::vector<uint32_t >& oSsrcVec)
	{
		int64_t tCurrentSeq = oDataCache->m_oSeqNum.Unwrap(oRTPHeader.sequenceNumber);
		int64_t t_time = getCurrentTicket();

		// 删除超时的记录

		int32_t iRet = EraseTimeOutPacket(oDataCache->m_oListSeq, t_time);
		oDataCache->m_uPacketCount += iRet;
		iRet = EraseTimeOutPacket(oDataCache->m_oListSeqMayMiss, t_time);
		oDataCache->m_uCumulativeLost += iRet;

		// 计算丢包数，乱序数，和丢包率
		SeqInfo tSeqInfo;

		tSeqInfo.m_iTimeStamp = t_time;
		bool t_isReset = (oDataCache->m_iTimeStampPre != 0) && (m_oRtpStateParameter.iTimeOutResetThreshold > 0) && (t_time - oDataCache->m_iTimeStampPre > m_oRtpStateParameter.iTimeOutResetThreshold) && (oDataCache->m_uPeerCsrc == 0);
		if (t_isReset)
		{
			// 记录需要重置的ssrc, 后面进行重置
			oSsrcVec.push_back(oDataCache->m_uPeerSsrc);
		}
		// 计算历史最大丢包率
		if (oDataCache->m_iTimeStampPreUpdate != 0 &&  (t_time - oDataCache->m_iTimeStampPreUpdate > m_oRtpStateParameter.iCacheDuration))
		{
			// 这里简化计算，直接用缓存中数据计算，不在取前一秒，因为很多情况重传都是新的ssrc, 除非是96 97 的情况，有少许误差，没有等待重传，影响不大
			int32_t n =  oDataCache->m_oListSeqMayMiss.size();
			int32_t d = oDataCache->m_oListSeq.size();

			float v = d > 0 ? n * 1.0f / d : 0;
			if (v > oDataCache->m_fFractionLostMax)
			{
				oDataCache->m_fFractionLostMax = v;
			}
			oDataCache->m_iTimeStampPreUpdate = t_time;
		}
		oDataCache->m_iTimeStampPre = t_time;

		/*计算累计乱序包*/
		if (oDataCache->m_iMaxSequenceNum < 0)
		{
			oDataCache->m_iMaxSequenceNum = tCurrentSeq;
			oDataCache->m_iMinSequenceNum = tCurrentSeq;

			oDataCache->m_iTimeStampPreUpdate = t_time;
			
		}
		else
		{
			uint64_t t_maxOutOrder = abs(tCurrentSeq - oDataCache->m_iMaxSequenceNum);
			if (t_maxOutOrder > oDataCache->m_uOutOfOrderDiffMax)
			{
				oDataCache->m_uOutOfOrderDiffMax = t_maxOutOrder;
			}
			
			if (tCurrentSeq < oDataCache->m_iMinSequenceNum)
			{
				// 更新最小值
				oDataCache->m_iMinSequenceNum = tCurrentSeq;
			}
			// 小于最大值判定属于乱序包
			if (tCurrentSeq < oDataCache->m_iMaxSequenceNum)
			{
				oDataCache->m_uOutOfOrderCount++;

				// 去掉可能晚到的包

				for (auto it = oDataCache->m_oListSeqMayMiss.begin(); it != oDataCache->m_oListSeqMayMiss.end();) {
					if (it->m_iSeq == tCurrentSeq) {
						it = oDataCache->m_oListSeqMayMiss.erase(it);
						break;
					}
					else
					{
						it++;
					}

				}

			}
			if (tCurrentSeq > oDataCache->m_iMaxSequenceNum)
			{

				int64_t dif = tCurrentSeq - oDataCache->m_iMaxSequenceNum;
				if (dif > 1)
				{
					// 有跳转，记录一下可能丢包的seq 
					for (int i = 0; i < dif - 1; i++)
					{
						tSeqInfo.m_iSeq = tCurrentSeq - i;
						tSeqInfo.m_iMaxSeq = tCurrentSeq;
						tSeqInfo.m_iTimeStamp = t_time;
						oDataCache->m_oListSeqMayMiss.push_back(tSeqInfo);
					}
				}

				oDataCache->m_iMaxSequenceNum = tCurrentSeq;
			}

		}

		oDataCache->m_iAccumulateByteSize += iByteSize;
		/*计算实时丢包率，计算前1S 时间内应该收到的包和真正丢的包(如果后1s 没有收到视为真正丢包)*/

		tSeqInfo.m_iSeq = tCurrentSeq;
		tSeqInfo.m_iMaxSeq = oDataCache->m_iMaxSequenceNum;
		tSeqInfo.m_iByteSize = oDataCache->m_iAccumulateByteSize;

		oDataCache->m_oListSeq.push_back(tSeqInfo);

	

	}

private:
	std::mutex m_mutex;
	std::map<uint32_t, std::shared_ptr<DataCache>> m_mapDate; // key = ssrc
	//int32_t m_iDuration = 2000; // 
	

	uint64_t m_uByteSize = 0;
	// 带宽计算，带宽计算不分ssrc, 只要是同一个Handle，所有ssrc在内的带宽 kbps
	std::list<SeqInfo> m_oListByte; // 
	RtpStateParameter m_oRtpStateParameter;

	bool m_bIsPause = false;

};

static std::mutex g_mutex;
static std::map<int32_t, std::shared_ptr<rtpState>> g_map;
static int32_t g_index = 0;



rtpState::Ptr GetPtr(int32_t key, bool isErase = false)
{
	rtpState::Ptr ptr;
	std::lock_guard<std::mutex> lk(g_mutex);
	std::map<int32_t, rtpState::Ptr>::iterator it = g_map.find(key);
	if (it != g_map.end())
	{
		ptr = it->second;
		if (isErase)
		{
			g_map.erase(it);
		}
	}
	return ptr;
}

int32_t CreateRtpState(const RtpStateParameter &oRtpStateParameter)
{
	std::shared_ptr<rtpState> ptr = std::make_shared<rtpState>(oRtpStateParameter);
	std::lock_guard<std::mutex> lk(g_mutex);
	g_index++;
	if (g_index >= 2147483647)
	{
		g_index = 1;
	}
	g_map[g_index] = ptr;
	return g_index;
}

int32_t DestoryRtpState(int32_t oHandle)
{
	rtpState::Ptr ptr = GetPtr(oHandle, true);
	if (ptr)
	{

		std::mutex _mutex;
		std::condition_variable _condition;
		
		while (1)
		{
			if (ptr.use_count() == 1)
			{
				ptr.reset();
				break;
			}
			//std::this_thread::sleep_for(std::chrono::milliseconds(1));

			std::unique_lock<std::mutex> lock(_mutex);
			_condition.wait_for(lock, std::chrono::milliseconds(1));
		}
	}
	return 0;
}

int32_t IncomingRtpState(int32_t oHandle, const int8_t* pData, int32_t iLen)
{
	rtpState::Ptr ptr = GetPtr(oHandle);
	if (!ptr) { printf("oHandle=%d is not exit \n", oHandle); return -1; }

	int32_t ret = ptr->IncomingRtp(pData, iLen);

	return ret; 
}
int32_t GetRtpStateNumOfSsrc(int32_t oHandle)
{
	rtpState::Ptr ptr = GetPtr(oHandle);
	if (!ptr) { printf("oHandle=%d is not exit \n", oHandle); return -1; }
	int32_t ret = ptr->GetRtpStateNumOfSsrc();
	return ret;

}
int32_t GetRtpStateInfo(int32_t oHandle, RtpState* oRtpStateArray, int32_t iMaxRtpStateNum)
{
	rtpState::Ptr ptr = GetPtr(oHandle);
	if (!ptr) { printf("oHandle=%d is not exit \n", oHandle); return -1; }

	int32_t ret = ptr->GetRtpStateInfo(oRtpStateArray, iMaxRtpStateNum);
	return ret;
}

//oHandle input 输入句柄 不会触发内部重置状态
// 暂停期间，实时丢包率为0 ,码率 0, 
// return 0 成功
int32_t RtpStatePause(int32_t oHandle)
{
	rtpState::Ptr ptr = GetPtr(oHandle);
	if (!ptr) { printf("oHandle=%d is not exit \n", oHandle); return -1; }
	return ptr->RtpStatePause();
	
}

//oHandle input 输入句柄 
// return 0 成功
int32_t RtpStateResume(int32_t oHandle)
{
	rtpState::Ptr ptr = GetPtr(oHandle);
	if (!ptr) { printf("oHandle=%d is not exit \n", oHandle); return -1; }
	return ptr->RtpStateResume();
}